﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.IO;
using System.Reflection;
using System.Configuration;
using YourWorldServer;
using System.Threading;

namespace GreenWorldWinService
{
    public partial class GreenWorldWinService : ServiceBase
    {
        private static readonly string ConfigurationFileName = "ServerConfigFile.config";
        private static readonly string WebServicesLocationKey = "WebServicesLocation";
        private static string webServicesLocation;

        private Thread runningThread;
        private SocketServer socketServer = null;
        private PolicyServer policyServer = null;

        public GreenWorldWinService()
        {
            InitializeComponent();
        }

        protected override void OnStart( string[] args )
        {
            base.OnStart( args );

            this.runningThread = new Thread( new ThreadStart( this.ThreadRun ) );
            this.runningThread.Start();
        }

        protected override void OnStop()
        {
            base.OnStop();

            if ( this.runningThread != null )
                this.runningThread.Abort();
        }

        private void ThreadRun()
        {
            Initialize();

            try
            {
                this.policyServer = new PolicyServer();
                this.policyServer.StartPolicyServer();

                this.socketServer = new SocketServer( webServicesLocation );
                this.socketServer.StartSocketServer();

                while ( true )
                {
                    ;
                }

                this.policyServer.StopPolicyServer();
                this.socketServer.StopSocketServer();
            }
            catch ( Exception e )
            {
                // Catch ThreadAbortEx and stop the sockets:
                if ( this.policyServer != null )
                    this.policyServer.StopPolicyServer();

                if ( this.socketServer != null )
                    this.socketServer.StopSocketServer();

                if ( e is ThreadAbortException == false )
                    Log.Instance.WriteException( e );
            }
        }

        private void Initialize()
        {
            string path = Path.GetDirectoryName( Assembly.GetExecutingAssembly().Location );
            string configFile = path + @"\" + ConfigurationFileName;

            ExeConfigurationFileMap configFileMap = new ExeConfigurationFileMap();
            configFileMap.ExeConfigFilename = configFile;

            Configuration config = null;
            try
            {
                config = ConfigurationManager.OpenMappedExeConfiguration( configFileMap, ConfigurationUserLevel.None );

                string[] keys = config.AppSettings.Settings.AllKeys;
                webServicesLocation = config.AppSettings.Settings[WebServicesLocationKey].Value;
            }
            catch ( Exception e )
            {
                Console.WriteLine( "Inicialization from the configuration file has failed. Please review the configuratin file." );

                Console.WriteLine( "Error details:" );
                Console.WriteLine( e.ToString() );
            }
        }

    }
}
